<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chrome LanguageModel Playground</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        #error-message {
            color: darkred;
            font-weight: bold;
        }
        #status-area {
            margin: 20px 0;
            padding: 15px;
            background-color: #f5f5f5;
            border-radius: 5px;
        }
        #download-area, #downloading-area {
            display: none;
        }
        #progress-bar {
            width: 100%;
            height: 20px;
            background-color: #e0e0e0;
            border-radius: 10px;
            overflow: hidden;
            margin: 10px 0;
        }
        #progress-fill {
            height: 100%;
            background-color: #4CAF50;
            width: 0%;
            transition: width 0.3s ease;
        }
        #prompt-area {
            display: none;
        }
        textarea {
            width: 100%;
            height: 100px;
            box-sizing: border-box;
        }
        button {
            padding: 10px 20px;
            margin: 5px;
            border: none;
            border-radius: 5px;
            background-color: #007bff;
            color: white;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        #response-area {
            white-space: pre-wrap;
            background-color: #f0f0f0;
            padding: 10px;
            margin-top: 10px;
            border-radius: 5px;
        }
        .history-item {
            border: 1px solid #ccc;
            padding: 10px;
            margin-bottom: 10px;
            border-radius: 5px;
        }
        .history-item .response {
            white-space: pre-wrap;
        }
        .timestamp {
            font-size: 0.8em;
            color: #666;
        }
        label[for="prompt-input"] {
            display: block;
            margin-bottom: 0.3em;
            font-weight: bold;
        }
        .status-indicator {
            display: inline-block;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            margin-right: 8px;
        }
        .status-available { background-color: #4CAF50; }
        .status-downloading { background-color: #FF9800; }
        .status-downloadable { background-color: #2196F3; }
        .status-unavailable { background-color: #f44336; }
    </style>
</head>
<body>
    <div id="error-message"></div>
    
    <div id="status-area">
        <h2>LanguageModel Status</h2>
        <div id="status-display">Checking availability...</div>
        
        <div id="download-area">
            <p>The language model needs to be downloaded before use.</p>
            <button id="download-button">Download Model</button>
        </div>
        
        <div id="downloading-area">
            <p>Downloading model...</p>
            <div id="progress-bar">
                <div id="progress-fill"></div>
            </div>
            <div id="progress-text">0%</div>
        </div>
    </div>
    
    <div id="prompt-area">
        <h1>Chrome LanguageModel Playground</h1>
        <p>Run prompts against the built-in language model in Chrome.</p>
        <label for="prompt-input">Prompt:</label>
        <textarea id="prompt-input" placeholder="Enter your prompt here..."></textarea>
        <button id="submit-button">Execute prompt</button>
        <div id="response-area" style="display: none;"></div>
    </div>
    
    <div id="history-area"></div>
    <p><small><a href="https://developer.chrome.com/docs/ai/built-in">About Chrome's built-in AI</a></small></p>

    <script>
        document.addEventListener('DOMContentLoaded', async () => {
            const errorMessage = document.getElementById('error-message');
            const statusArea = document.getElementById('status-area');
            const statusDisplay = document.getElementById('status-display');
            const downloadArea = document.getElementById('download-area');
            const downloadingArea = document.getElementById('downloading-area');
            const downloadButton = document.getElementById('download-button');
            const progressFill = document.getElementById('progress-fill');
            const progressText = document.getElementById('progress-text');
            const promptArea = document.getElementById('prompt-area');
            const promptInput = document.getElementById('prompt-input');
            const submitButton = document.getElementById('submit-button');
            const responseArea = document.getElementById('response-area');
            const historyArea = document.getElementById('history-area');

            let currentSession = null;

            // Check if LanguageModel is available
            if (!window.LanguageModel) {
                errorMessage.innerHTML = `
                <h2>LanguageModel API not found</h2>
                <p>This requires Chrome 129+ with the "Built-in AI Early Preview Program" enabled.</p>
                <p>Visit <code>chrome://flags/#optimization-guide-on-device-model</code> and enable the flag.</p>
                <p>You may also need to restart Chrome and wait for the model to download.</p>
                `;
                statusArea.style.display = 'none';
                return;
            }

            async function checkAvailability() {
                try {
                    const availability = await window.LanguageModel.availability();
                    updateStatus(availability);
                    return availability;
                } catch (error) {
                    console.error('Error checking availability:', error);
                    statusDisplay.innerHTML = `<span class="status-indicator status-unavailable"></span>Error checking availability: ${error.message}`;
                    return 'unavailable';
                }
            }

            function updateStatus(status) {
                downloadArea.style.display = 'none';
                downloadingArea.style.display = 'none';
                promptArea.style.display = 'none';

                switch (status) {
                    case 'available':
                        statusDisplay.innerHTML = '<span class="status-indicator status-available"></span>Model is ready to use!';
                        promptArea.style.display = 'block';
                        break;
                    
                    case 'downloadable':
                        statusDisplay.innerHTML = '<span class="status-indicator status-downloadable"></span>Model is available for download';
                        downloadArea.style.display = 'block';
                        break;
                    
                    case 'downloading':
                        statusDisplay.innerHTML = '<span class="status-indicator status-downloading"></span>Model is currently downloading';
                        downloadingArea.style.display = 'block';
                        // Check periodically if download is complete
                        setTimeout(checkAvailability, 2000);
                        break;
                    
                    case 'unavailable':
                    default:
                        statusDisplay.innerHTML = '<span class="status-indicator status-unavailable"></span>Language model is not supported on this device';
                        break;
                }
            }

            downloadButton.addEventListener('click', async () => {
                try {
                    downloadButton.disabled = true;
                    downloadButton.textContent = 'Starting download...';
                    
                    currentSession = await window.LanguageModel.create({
                        monitor(m) {
                            m.addEventListener('downloadprogress', (e) => {
                                const percentage = Math.round(e.loaded * 100);
                                progressFill.style.width = percentage + '%';
                                progressText.textContent = percentage + '%';
                                console.log(`Downloaded ${percentage}%`);
                            });
                        },
                    });
                    
                    // Download started, update UI
                    updateStatus('downloading');
                    
                } catch (error) {
                    console.error('Error starting download:', error);
                    downloadButton.disabled = false;
                    downloadButton.textContent = 'Download Model';
                    statusDisplay.innerHTML = `<span class="status-indicator status-unavailable"></span>Error starting download: ${error.message}`;
                }
            });

            submitButton.addEventListener('click', async () => {
                const prompt = promptInput.value.trim();
                if (!prompt) return;
                
                responseArea.style.display = 'block';
                responseArea.textContent = 'Generating response...';
                submitButton.disabled = true;
                submitButton.textContent = 'Generating...';

                try {
                    // Create session if we don't have one
                    if (!currentSession) {
                        currentSession = await window.LanguageModel.create();
                    }
                    
                    const response = await currentSession.prompt(prompt);
                    responseArea.textContent = response;
                    
                    saveToHistory(prompt, response);
                    displayHistory();
                    
                } catch (error) {
                    console.error('Error generating response:', error);
                    responseArea.textContent = `Error: ${error.message}`;
                } finally {
                    submitButton.disabled = false;
                    submitButton.textContent = 'Execute prompt';
                }
            });

            function saveToHistory(prompt, response) {
                try {
                    const history = JSON.parse(localStorage.getItem('languageModelHistory') || '[]');
                    history.unshift({
                        prompt,
                        response,
                        timestamp: new Date().toISOString()
                    });
                    // Keep only last 50 items
                    if (history.length > 50) {
                        history.splice(50);
                    }
                    localStorage.setItem('languageModelHistory', JSON.stringify(history));
                } catch (error) {
                    console.warn('Could not save to localStorage:', error);
                }
            }

            function displayHistory() {
                try {
                    const history = JSON.parse(localStorage.getItem('languageModelHistory') || '[]');
                    if (!history.length) {
                        historyArea.innerHTML = '';
                        return;
                    }
                    
                    historyArea.innerHTML = '<h2>History</h2>';

                    history.forEach((item, index) => {
                        const historyItem = document.createElement('div');
                        historyItem.className = 'history-item';
                        historyItem.innerHTML = `
                            <p><strong>Prompt:</strong> ${escapeHtml(item.prompt)}</p>
                            <p class="response"><strong>Response:</strong> ${escapeHtml(item.response)}</p>
                            <p class="timestamp">Timestamp: ${new Date(item.timestamp).toLocaleString()}</p>
                            <button class="delete-button" data-index="${index}">Delete</button>
                        `;
                        historyArea.appendChild(historyItem);
                    });

                    document.querySelectorAll('.delete-button').forEach(button => {
                        button.addEventListener('click', (e) => {
                            const index = e.target.getAttribute('data-index');
                            deleteHistoryItem(index);
                        });
                    });
                } catch (error) {
                    console.warn('Could not load history:', error);
                }
            }

            function deleteHistoryItem(index) {
                try {
                    const history = JSON.parse(localStorage.getItem('languageModelHistory') || '[]');
                    history.splice(index, 1);
                    localStorage.setItem('languageModelHistory', JSON.stringify(history));
                    displayHistory();
                } catch (error) {
                    console.warn('Could not delete history item:', error);
                }
            }

            function escapeHtml(text) {
                const div = document.createElement('div');
                div.textContent = text;
                return div.innerHTML;
            }

            // Initialize
            await checkAvailability();
            displayHistory();
        });
    </script>
</body>
</html>
